package com.itmuch.box.service.content;

import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Sets;
import com.itmuch.box.core.base.BaseService;
import com.itmuch.box.core.security.SubjectUtil;
import com.itmuch.box.dao.content.ContentArticleRepository;
import com.itmuch.box.dao.elastic.ArticleElasticRepository;
import com.itmuch.box.dao.mid.MidContentRecomendRepository;
import com.itmuch.box.dao.mid.MidContentTagRepository;
import com.itmuch.box.domain.category.entity.Category;
import com.itmuch.box.domain.content.entity.Content;
import com.itmuch.box.domain.content.entity.ContentArticle;
import com.itmuch.box.domain.content.vo.ArticleAddVo;
import com.itmuch.box.domain.content.vo.ArticleEditVo;
import com.itmuch.box.domain.content.vo.ContentVo;
import com.itmuch.box.domain.elastic.entity.ArticleElastic;
import com.itmuch.box.domain.mid.entity.MidContentRecomend;
import com.itmuch.box.domain.mid.entity.MidContentTag;
import com.itmuch.box.domain.tag.entity.Tag;
import com.itmuch.box.service.category.CategoryService;
import com.itmuch.box.service.tag.TagService;
import com.itmuch.box.util.DozerUtil;
import com.itmuch.box.util.OrikaUtil;
import com.itmuch.box.util.StringUtil;

@Service
@Transactional
public class ContentArticleService extends BaseService<ContentArticleRepository, ContentArticle> {
    @Autowired
    private ArticleElasticRepository articleElasticRepository;
    @Autowired
    private TagService tagService;
    @Autowired
    private ContentService contentService;
    @Autowired
    private MidContentTagRepository midContentTagRepository;
    @Autowired
    private MidContentRecomendRepository midContentRecomendRepository;
    @Resource
    private CategoryService categoryService;

    public void insertArticle(ArticleAddVo vo) {
        Integer memberId = SubjectUtil.getSubjectId();

        // f_content
        Content content = DozerUtil.map(vo, Content.class);
        content.setMemberId(memberId);
        content.setModelId(1);
        Content content2 = this.contentService.insert(content);

        // content_article
        ContentArticle article = DozerUtil.map(vo, ContentArticle.class);
        this.insert(article);

        // tags
        String tagsString = vo.getTagsString();
        if (!StringUtils.isEmpty(tagsString)) {
            Set<MidContentTag> midContentTags = Sets.newHashSet();
            Set<String> tagSet = StringUtil.splitAndTrim(tagsString, ",");
            if (!tagSet.isEmpty()) {
                for (String tagName : tagSet) {
                    Tag tagInDB = this.tagService.findTopByName(tagName);
                    // 该标签已经存在
                    if (tagInDB != null) {
                        // tags.add(tagInDB);
                        MidContentTag midContentTag = new MidContentTag();
                        midContentTag.setContentId(content2.getId());
                        midContentTag.setTagId(tagInDB.getId());
                        midContentTags.add(midContentTag);
                    }
                    // 该标签不存在
                    else {
                        // ① 新建标签
                        Tag tag = new Tag();
                        tag.setName(tagName);
                        Tag newTag = this.tagService.insert(tag);

                        MidContentTag midContentTag = new MidContentTag();
                        midContentTag.setContentId(content2.getId());
                        midContentTag.setTagId(newTag.getId());
                        midContentTags.add(midContentTag);
                    }
                }
            }
            this.midContentTagRepository.save(midContentTags);
        }

        // 推荐
        Set<Integer> recomendIds = vo.getRecomendIds();
        if (CollectionUtils.isNotEmpty(recomendIds)) {
            Set<MidContentRecomend> midContentRecomends = Sets.newHashSet();
            for (Integer recomendId : recomendIds) {
                MidContentRecomend midContentRecomend = new MidContentRecomend();
                midContentRecomend.setContentId(content2.getId());
                midContentRecomend.setRecomendId(recomendId);
                midContentRecomends.add(midContentRecomend);
            }
            this.midContentRecomendRepository.save(midContentRecomends);
        }

        // 插入文章到elastic
        ArticleElastic articleElastic = DozerUtil.map(vo, ArticleElastic.class);
        articleElastic.setId(content.getId());
        this.articleElasticRepository.save(articleElastic);
    }

    public ArticleEditVo findArticleById(Integer id) {
        Content content = this.contentService.findOne(id);
        if (content != null) {
            ArticleEditVo editVo = DozerUtil.map(content, ArticleEditVo.class);

            ContentArticle contentArticle = this.dao.findOne(id);

            DozerUtil.map(contentArticle, editVo);
            return editVo;
        }
        // 没找到该文章
        else {
            return null;
        }
    }

    public void updateArticle(ArticleEditVo editVo) {
        Integer contentId = editVo.getId();
        // 不修改member_id
        // f_content
        // 修改article
        Content content = this.contentService.findOne(contentId);

        OrikaUtil.map(editVo, content);
        this.contentService.update(content);

        // content_article
        ContentArticle contentArticle = this.findOne(editVo.getId());
        DozerUtil.map(editVo, contentArticle);
        this.update(contentArticle);

        // tags
        String tagsString = editVo.getTagsString();
        if (!StringUtils.isEmpty(tagsString)) {
            Set<MidContentTag> midContentTags = Sets.newHashSet();
            Set<String> tagSet = StringUtil.splitAndTrim(tagsString, ",");
            if (!tagSet.isEmpty()) {
                for (String tagName : tagSet) {
                    Tag tagInDB = this.tagService.findTopByName(tagName);
                    // 该标签已经存在
                    if (tagInDB != null) {
                        MidContentTag midContentTag = new MidContentTag();
                        midContentTag.setContentId(contentId);
                        midContentTag.setTagId(tagInDB.getId());
                        midContentTags.add(midContentTag);
                    }
                    // 该标签不存在
                    else {
                        // ① 新建标签
                        Tag tag = new Tag();
                        tag.setName(tagName);
                        Tag newTag = this.tagService.insert(tag);

                        MidContentTag midContentTag = new MidContentTag();
                        midContentTag.setContentId(contentId);
                        midContentTag.setTagId(newTag.getId());
                        midContentTags.add(midContentTag);
                    }
                }
            }
            Set<MidContentTag> findByContentId = this.midContentTagRepository.findByContentId(contentId);
            this.midContentTagRepository.deleteInBatch(findByContentId);
            this.midContentTagRepository.save(midContentTags);
        }

        // 推荐
        Set<Integer> recomendIds = editVo.getRecomendIds();
        if (CollectionUtils.isNotEmpty(recomendIds)) {
            Set<MidContentRecomend> midContentRecomends = Sets.newHashSet();
            for (Integer recomendId : recomendIds) {
                MidContentRecomend midContentRecomend = new MidContentRecomend();
                midContentRecomend.setContentId(contentId);
                midContentRecomend.setRecomendId(recomendId);
                midContentRecomends.add(midContentRecomend);
            }
            Set<MidContentRecomend> set = this.midContentRecomendRepository.findByContentId(contentId);
            // 删除原先的关系
            this.midContentRecomendRepository.deleteInBatch(set);
            this.midContentRecomendRepository.save(midContentRecomends);
        }

        // 修改文章到elastic
        ArticleElastic articleElastic = DozerUtil.map(editVo, ArticleElastic.class); // .map(vo, ArticleElastic.class);
        articleElastic.setId(content.getId());
        this.articleElasticRepository.save(articleElastic);
    }

    public ContentVo findArticleById2(Integer id) {
        Content content = this.contentService.findOne(id);
        if (content != null) {
            ContentArticle contentArticle = this.findOne(id);
            Category category = this.categoryService.findOne(content.getCategoryId());

            ContentVo vo = new ContentVo();
            vo.setContent(content);
            vo.setArticle(contentArticle);
            vo.setCategory(category);
            return vo;
        }
        return null;
    }

    public void deleteArticleById(Integer id) {
        this.contentService.delete(id);
        ContentArticle findOne = this.dao.findOne(id);
        if (findOne != null) {
            this.delete(id);
        }
    }

}
